package com.sunday.common.core.permissions;

import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 权限解密计算
 * @Author: zsy
 */
@Slf4j
public class PermissionsDecode<T> {

    /**
     * 缓存
     */
    private Map<String, T> permissionMapper;

    /**
     * 分类器
     */
    private Function<T, Integer> classifier;

    /**
     * 映射关系
     */
    private Function<T, Long> mapper;

    /**
     * 构建解码器
     *
     * @param collection 构建基础数据
     * @param keyMapper  缓存分组key
     * @param classifier 分类器
     * @param mapper     映射关系
     * @return {@link null}
     */
    public PermissionsDecode(Collection<T> collection, Function<T, String> keyMapper, Function<T, Integer> classifier, Function<T, Long> mapper) {
        this.permissionMapper = collection.stream().collect(Collectors.toMap(keyMapper, Function.identity()));
        this.classifier = classifier;
        this.mapper = mapper;
    }

    /**
     * 权限是否通过
     *
     * @param targetUrl
     * @param permissionSum
     * @return {@link boolean}
     */
    public boolean check(String targetUrl, long[] permissionSum) {
        assert targetUrl != null : "targetUrl must not be null";
        assert permissionSum != null && permissionSum.length > 0 : "permissionSum must not be null";
        return Optional.ofNullable(permissionMapper.get(targetUrl))
                .filter(permission -> (permissionSum.length - 1) >= classifier.apply(permission))
                .map(permission -> (permissionSum[classifier.apply(permission)] & mapper.apply(permission)) != 0)
                .orElse(false);
    }

    public static <T> PermissionsDecode of(Collection<T> collection, Function<T, String> keyMapper, Function<T, Integer> classifier, Function<T, Long> mapper) {
        return new PermissionsDecode(collection, keyMapper, classifier, mapper);
    }

}
